﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using GalaSoft.MvvmLight.Command;

namespace Dsl.Ped.Framework.Projections.CollectionProjections.Vertical
{
    /// <summary>
    /// Projection that organize the items vertically
    /// </summary>
    public class VerticalProjection : ItemsControl
    {
        #region Fields

        private ListView ItemsListView { get; set; }

        /// <summary>
        /// Command executed when one is trying to remove a specific item from the projection
        /// </summary>
        private RelayCommand<object> removeItemCommand; 

        /// <summary>
        /// <see cref="DependencyProperty"/> representing the predicated for the filtering of
        /// presented items in a projection
        /// </summary>
        public static DependencyProperty ItemsFilterProperty;

        /// <summary>
        /// <see cref="DependencyProperty"/> representing an action executed when the one requires
        /// to remove a specific item from the projection
        /// </summary>
        public static DependencyProperty RemoveItemProperty;

        #endregion

        #region Constructors

        /// <summary>
        /// Static constructor, registers all <see cref="DependencyProperty"/> properties
        /// </summary>
        static VerticalProjection()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(VerticalProjection), new FrameworkPropertyMetadata(typeof(VerticalProjection)));

            ItemsFilterProperty = DependencyProperty.Register(
                "ItemsFilter", typeof(Predicate<object>), typeof(VerticalProjection),
                    new FrameworkPropertyMetadata(null));

            RemoveItemProperty = DependencyProperty.Register(
                "RemoveItem", typeof(Action<object>), typeof(VerticalProjection),
                    new FrameworkPropertyMetadata(new Action<object>(member => {})));
        }

        #endregion

        #region Members

        /// <summary>
        /// Gets or sets the filter of the items. Items in the projection can be filtered by a predicated
        /// </summary>
        public Predicate<object> ItemsFilter
        {
            get { return (Predicate<object>) this.GetValue(ItemsFilterProperty); }
            set { SetValue(ItemsFilterProperty, value); }
        }

        /// <summary>
        /// Gets the command that removes items from the projection
        /// </summary>
        public RelayCommand<object> RemoveItemCommand
        {
            get
            {
                return removeItemCommand ?? (removeItemCommand = new RelayCommand<object>(RemoveItem));
            }
        }

        /// <summary>
        /// Gets or sets the action that removes the item from the projection
        /// </summary>
        public Action<object> RemoveItem
        {
            get { return (Action<object>)this.GetValue(RemoveItemProperty); }
            set { SetValue(RemoveItemProperty, value); }
        }

        #endregion

        #region Methods

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.ItemsListView = (ListView)GetTemplateChild("PART_ItemsListView");

            var newView1 = new CollectionViewSource() { Source = this.ItemsSource };
            var listCollectionView = (ListCollectionView)newView1.View;
            if (this.ItemsFilter != null)
            {
                listCollectionView.Filter = this.ItemsFilter;
            }
            this.ItemsListView.ItemsSource = listCollectionView;
        }

        #endregion
    }
}
